package com.hk.alipay.security;

import com.alipay.api.AlipayResponse;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import com.hk.commons.enums.AreaCodeEnum;
import com.hk.commons.util.AssertUtils;
import com.hk.commons.util.Constants;
import com.hk.core.authentication.api.UserPrincipal;
import com.hk.core.authentication.api.enums.ThirdAccountType;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

import java.util.Map;
import java.util.function.Function;

/**
 * @author Kevin
 * @date 2019/3/5 17:50
 */
public record AliPayAuthenticationProvider(
        Function<String, UserPrincipal> function) implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        var aliPayResponse = (AlipayResponse) authentication.getPrincipal();
        UserPrincipal principal = null;
        if (aliPayResponse instanceof AlipayUserInfoShareResponse userInfo) {
            principal = function != null ? function.apply(userInfo.getUserId())
                    : aliPayUserInfoShare(userInfo);
        } else if (aliPayResponse instanceof AlipaySystemOauthTokenResponse oauth2TokenUserInfo) {
            principal = function != null ? function.apply(oauth2TokenUserInfo.getUserId())
                    : aliPayOauth2TokenUserInfo(oauth2TokenUserInfo);
        }
        AssertUtils.notNull(principal, "认证信息不能为空.");
        return new AliPayAuthenticationToken(principal, null);
    }

    /**
     * @param userInfo userInfo
     */
    private UserPrincipal aliPayOauth2TokenUserInfo(AlipaySystemOauthTokenResponse userInfo) {
        var principal = new UserPrincipal();
        principal.setAdditionalInfo(Map.of(ThirdAccountType.ALI.name(), String.valueOf(true), Constants.ALI_USER_ID, userInfo.getUserId()));
        return principal;
    }

    private UserPrincipal aliPayUserInfoShare(AlipayUserInfoShareResponse userInfo) {
        return new UserPrincipal()
                .setAdditionalInfo(Map.of(ThirdAccountType.ALI.name(), String.valueOf(true), Constants.ALI_USER_ID, userInfo.getUserId()))
                .setAccount(userInfo.getUserId())
                .setRealName(userInfo.getUserName())
                .setIconPath(userInfo.getAvatar())
                .setEmail(userInfo.getEmail())
                .setAreaCode(AreaCodeEnum.CHINA.getCode())
                .setMobileNumber(userInfo.getPhone());
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return AliPayAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
